import { assert, NodePool, AudioClip, AudioSource, director, Prefab, resources, Node, instantiate } from "cc";
import Singleton from "../base/Singleton";
import { Epath, EPrefabName } from "../../enum";
import { PlayerData } from "../PlayerData";
import { PoolManager } from "./PoolManager";
import EventCenter from "./EventCenter";
import { AudioManager } from "./AudioManager";

/** 游戏数据保存的key */
export const GAME_SAVING_KEY = '__DUNGOEN_SHOOTER__';


/** 保存数据到本地 */
function saveToLocal(data: {}) {
    try {
        localStorage.setItem(GAME_SAVING_KEY, JSON.stringify(data));
        console.log('保存成功');
    } catch (error) {
        console.error('保存失败', error);
    }
}

/** 从本地加载数据 */
function loadFromLocal(): {} | null {
    try {
        let data = localStorage.getItem(GAME_SAVING_KEY);
        if (data && data.length > 0) {
            return JSON.parse(data);
        } else {
            return null;
        }
    } catch (error) {
        console.error('加载失败', error);
        return null;
    }
}


/** 核心类 */
export class Core extends Singleton {
    static get instance() {
        return super.GetInstance<Core>();
    }

    private constructor() {
        super();

    }

    private _prefabCaches: Record<string, Prefab> = {};


    playerData: PlayerData = new PlayerData();
    event: EventCenter = new EventCenter();
    poolManager: PoolManager = new PoolManager();
    audioManager: AudioManager = new AudioManager();

    init(onFinished?: () => void) {

        let perisitNode = new Node('AudioSourceNode');
        director.getScene().addChild(perisitNode);
        director.addPersistRootNode(perisitNode);
        this.audioManager.init(perisitNode.addComponent(AudioSource));

        let data = loadFromLocal();
        if (data) {
            console.log('老用户')
            this.playerData.setPackage(data);
        } else {
            // TODO 新用户
        }

        console.log('核心方法init')
        console.log('玩家数据管理', this.playerData)
        console.log('对象池管理', this.poolManager)
        console.log('音频管理', this.audioManager)


        let prefabPromisesTasks: Promise<void>[] = [];

        Object.keys(EPrefabName).forEach(key => {
            let name = EPrefabName[key];
            let url = Epath.PREFAB_PATH + name;
            prefabPromisesTasks.push(new Promise((resolve, reject) => {
                resources.load(url, (err, prefab) => {
                    if (err) {
                        console.error("预制体加载失败", err);
                        reject();

                        return;
                    }
                    this._prefabCaches[name] = prefab as Prefab;
                    resolve();
                });
            }))
        });
        Promise.all(prefabPromisesTasks).then(() => {
            console.log('所有预制体加载完成');
            onFinished?.();
        }).catch(() => {
            console.log('有预制体加载失败');
        });
    }

    /** 保存游戏的方法 */
    save() {
        console.log('TODOsave内容是自己写的需要校对')
        console.log(this.playerData.getPackage())
        saveToLocal(this.playerData.getPackage());
    }


    /** 创建节点 */
    createNode(name: string, parent?: Node): Node {
        let prefab = this._prefabCaches[name];
        if (!prefab) {
            console.warn('没有找到对应的预制体:', name);
            return;
        }
        let node = instantiate(prefab);
        node.parent = parent;
        return node;
    }

    /**
     * 根据名称和父节点从节点池中获取节点
     * @param name 节点的名称，用于从预设字典中查找对应的预设
     * @param parent 节点的父节点，用于设置新获取节点的父节点
     * @returns 返回从节点池中获取的节点
     */
    getNode(name: string, parent: Node) {
        const prefab = this._prefabCaches[name];
        if (!prefab) {
            console.warn('没有找到对应的预制体:', name);
            return null;
        }
        const node = this.poolManager.get(prefab);
        if (node) {
            node.parent = parent;
        }
        return node;
    }

    /**
     * 将节点放入节点池
     * @param node 要放入节点池的节点
     */
    putNode(node: Node) {
        this.poolManager.put(node);
    }



}




